#include <netpacket/packet.h> // struct ifreq
#include <sys/ioctl.h>        // ioctl
#include <string.h>           // memset
#include <stdio.h>            // perror
#include <sys/socket.h>       // sendto
#include <net/if.h>           // struct ifreq
#include "tools.h"
/****************************************************************
函数: int send_msg(int sockfd, unsigned char* msg, char *if_name)
功能: 通用发送函数
参数: 文件描述符、报文、报文长度、网卡信息
返回值: 发送字节数
*****************************************************************/
int send_msg(int sockfd, unsigned char *msg, int len, char *if_name)
{
    struct ifreq ethreq;                            // 网卡结构体
    strncpy(ethreq.ifr_name, if_name, IFNAMSIZ);    // 指定网卡名
    if (-1 == ioctl(sockfd, SIOCGIFINDEX, &ethreq)) // SIOCGIFINDEX 获取接口地址
    {
        perror("SIOCGIFINDEX ioctl");
        return -1;
    }
    struct sockaddr_ll sll;
    memset(&sll, 0, sizeof(sll));
    sll.sll_ifindex = ethreq.ifr_ifindex;
    return sendto(sockfd, msg, len, 0, (struct sockaddr *)&sll, sizeof(sll));
}

/****************************************************************
函数: unsigned short checksum(unsigned short *buf, int len)
功能: 校验和
参数: 报文 报文长度
返回值: 计算结果
*****************************************************************/
unsigned short checksum(unsigned short *buf, int len)
{
    int nword = len / 2;
    unsigned long sum;

    if (len % 2 == 1)
        nword++;
    for (sum = 0; nword > 0; nword--)
    {
        sum += *buf;
        buf++;
    }
    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    return ~sum;
}